package cz.pproproj.aaservice.dldapmodule;

import cz.pproproj.aaservice.guimodule.model.AuthenticationException;
import cz.pproproj.aaservice.aasbllmodule.authentication.AuthenticationUser;
import cz.pproproj.aaservice.aasbllmodule.authentication.AuthenticationDataAccess;
import org.springframework.ldap.core.support.LdapContextSource;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * @author David
 * @since 18. 1. 2015
 */
public class LdapAuthenticationDataAccessImpl implements AuthenticationDataAccess {

    private final String _configurationDirName;
    LdapContextSource ldapContextSource;

    public LdapAuthenticationDataAccessImpl(String configurationDirName) {
        _configurationDirName = configurationDirName;
        ldapServerConfigure(_configurationDirName);
    }

    @Override
    public boolean authenticate(AuthenticationUser user) throws AuthenticationException {

        Credentials credentials = new Credentials();
        credentials.setUser(user.getUserName());
        credentials.setPassword(user.getPassword());

        AuthenticationManager authenticationManager = new AuthenticationManager(ldapContextSource);
        return authenticationManager.authenticate(credentials);
    }

    @Override
    public String addUser(AuthenticationUser user) throws AuthenticationException {

        throw new UnsupportedOperationException("Operation addUser is not supported for LDAP server.");

    }

    @Override
    public void deleteUser(AuthenticationUser user) throws AuthenticationException {

        throw new UnsupportedOperationException("Operation deleteUser is not supported for LDAP server.");

    }

    @Override
    public String getConfigurationDirName() {
        return _configurationDirName;
    }

    @Override
    public List<AuthenticationUser> getAllUsers() {
        return null;
    }

    private void ldapServerConfigure(String dataSource) {

        Properties prop = new Properties();
        InputStream input = null;

        try {

            input = getClass().getResourceAsStream("/ldapconfigurations/" + dataSource + "/ldapconnection.properties");

            prop.load(input);

            ldapContextSource = new LdapContextSource();

            ldapContextSource.setUrl(prop.getProperty("ldap.url") + ":" + prop.getProperty("ldap.port"));
            ldapContextSource.setBase(prop.getProperty("ldap.base"));
            ldapContextSource.afterPropertiesSet();

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
